package top.q3747051.cq;

import org.bukkit.plugin.Plugin;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.function.Consumer;

/**
 * @author Xiaodai
 * @since 2018.02.25
 */
public class CQSocketManager implements AutoCloseable, Closeable {

    private final ServerSocket server;
    private final Consumer<String> receiver;
    private final Plugin p;
    private PrintWriter client;

    private synchronized void setClient(PrintWriter client){
        this.client = client;
    }

    public CQSocketManager(Plugin p, int port, Consumer<String> receiver) throws IOException {
        this.p = p;
        this.server = new ServerSocket(port);
        this.receiver = receiver;
    }

    public void listen(){
        new Thread(() -> {
            try{
                Socket s =server.accept();
                p.getLogger().info("Client connected! I=" + s.getLocalAddress().getHostName());
                setClient(new PrintWriter(s.getOutputStream()));
                BufferedReader read = new BufferedReader(new InputStreamReader(s.getInputStream()));
                String msg;
                while((msg = read.readLine()) != null){
                    // Switch into main thread
                    String msg1 = msg;
                    p.getServer().getScheduler().runTask(p, () -> {
                        // Here can be a bit easier.
                        // I used Consumer just for demo and extendable.
                        receiver.accept(msg1);
                    });
                }
                p.getLogger().info("Thread stop - 1");
                s.close();
                client.close();
                read.close();
                listen();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }


    // Exception may throw.
    // Process yourself.
    public void send(String s) {
        client.write(s);
        client.flush();
    }



    @Override
    public void close() {

        client.close();

        try{
            server.close();
        }catch (IOException e){
            e.printStackTrace();
        }

    }
}
